<template>
	<div class="setup">
		<h2>1.ref ,reactive 定义响应式数据</h2>
		<div>{{title}}{{userInfos.username}}---{{userInfos.age}}</div>
		<br />
		<button @click="getUserName">获取用户名称</button>
		<br />
		<div>双向数据绑定 影响ref,reactive</div>
		<br />
		<input v-model="title" />
		<input v-model="userInfos.username" />
		<h2>2.toRefs 解构响应式对象数据</h2>
		<br />
		{{worksName}}
		<input v-model="worksName" />
		<h2>3.computed ：计算属性</h2>
		<input v-model="firstName" />
		<input v-model="lastName" />
		<div>{{fullName}}</div>
		<h2>4.watchEffet 监听数据变化 --侦听器</h2>
		<div>{{data.count}}</div>
		<button @click="stop">手动关闭侦听器</button>

		<h2>5.watch 监听数据变化 --侦听器</h2>
		<div>{{data.count}}</div>
		<div>watch 双向数据绑定，前后数据</div>
		{{numVal}}
		<input v-model="numVal" />
		<input v-model="data.count" />
		<br />
	</div>
</template>

<script>
import {
	ref,
	reactive,
	toRefs,
	computed,
	watchEffect,
	watch,
	onMounted,
	onBeforeMount
} from "vue";
export default {
	setup() {
		// 1. ref ,reactive 定义响应式数据
		// ref 【定义字符串，num,bool，数组】
		// reactive【定义对象】
		var title = ref("用户信息：");
		var userInfos = reactive({
			username: "张三",
			age: 20
		});

		// 定义方法
		var getUserName = () => {
			// 获取reactive的数据
			console.log("username:", userInfos.username);
			//获取ref 的数据
			console.log("title:", title.value);

			// 修改reactive的数据
			userInfos.username = "张艺";
			//修改ref 的数据
			title.value = "改变用户信息：";
		};
		// 2.toRefs 解构响应式对象数据
		var worksInfos = reactive({
			worksName: "张三",
			worksDesi: "到好多好好的"
		});

		//3.computed ：计算属性
		var userInfos2 = reactive({
			firstName: "王",
			lastName: "一搏"
		});

		var fullName = computed(() => {
			return userInfos2.firstName + userInfos2.lastName;
		});

		// 4.watchEffet 监听数据变化 --侦听器
		const data = reactive({
			count: 10,
			num: 1
		});
		// const stop = watchEffect(() => {
		// 	console.log("侦听器：", data.count);
		// });
		// setInterval(() => {
		// 	data.count++;
		// }, 1000);

		// 5.watch 监听数据变化 --侦听器
		// (1).简单的引用
		// 要监听对象data ，但是不能监听对象里的值data.count
		// watch(data, () => {
		// 	console.log("watch 监听：", data.count);
		// });
		// setInterval(() => {
		// 	data.count++;
		// }, 1000);

		var numVal = ref("1");
		// (2).watch 的两个参数，代表新的值和旧的值
		watch(numVal, (newVal, oldVal) => {
			console.log("numVal新值跟旧值的变化:", newVal, oldVal);
		});

		//(3). watch 多个值，返回的也是多个值的数组
		watch([numVal, data], (newValue, oldValue) => {
			console.log("old", oldValue); //["13",Proxy {count: "144", num: 1}]
			console.log("new", newValue); //["134",Proxy {count: "144", num: 1}]
		});

		// (4).使用 getter 的写法 watch reactive 对象中的一项
		watch([numVal, () => data.count], (newValue, oldValue) => {
			console.log("old", oldValue); //old (2) ["1", 10]
			console.log("new", newValue); //new (2) ["1", "103"]
			console.log("updated:" + numVal.value + data.count); //updated:1103
		});
		// 6. 生命周期

		// mounted
		onMounted(() => {
			// console.log("Component is mounted!");
		});

		return {
			title,
			userInfos,
			getUserName,
			...toRefs(worksInfos), //...worksInfos  这样的话可以显示数据，但是不能双向绑定数据
			...toRefs(userInfos2),
			fullName,
			data,
			stop,
			numVal
		};
	}
};
</script>
<!--
一.setup
    1. setup 函数会在 beforeCreate 之后、created 之前执行
    2. setup 有2个参数
        props 的父组件传递过来的参数
        ctx 上下文对象
            ctx.attrs
            ctx.slots
            ctx.parent
            ctx.root
            ctx.emit
            ctx.refs
    3.在 setup() 函数中无法访问到 this

-->
